package com.miracle.moa.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miracle.common.Result;
import com.miracle.common.StatusCode;
import com.miracle.moa.manager.entity.Dept;
import com.miracle.moa.manager.entity.Role;
import com.miracle.moa.manager.entity.User;
import com.miracle.moa.manager.entity.UserRole;
import com.miracle.moa.manager.mapper.UserMapper;
import com.miracle.moa.manager.service.IDeptService;
import com.miracle.moa.manager.service.IRoleService;
import com.miracle.moa.manager.service.IUserRoleService;
import com.miracle.moa.manager.service.IUserService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author miracle
 * @since 2021-03-22
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private IDeptService deptService;

    @Override
    public User findUserAndRole(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getUserName, username);
        User user = super.getOne(queryWrapper);
        List<Role> roles = roleService.findAllRoleByUserId(user.getId());
        user.setRoles(roles);
        return user;
    }

    @Override
    public IPage<User> listAllUser(int page, int pageSize, User user) {
        Page<User> userPage = new Page<>(page, pageSize);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(user.getUserName())) {
            queryWrapper.like("user_name", user.getUserName());
        }
        if (StringUtils.isNotEmpty(user.getEmail())) {
            queryWrapper.like("email", user.getEmail());
        }
        if (StringUtils.isNotEmpty(user.getRealName())) {
            queryWrapper.like("real_name", user.getRealName());
        }
        if (StringUtils.isNotEmpty(user.getPhoneNum())) {
            queryWrapper.like("phone_num", user.getPhoneNum());
        }
        if (StringUtils.isNotEmpty(user.getUserEdu())) {
            queryWrapper.eq("user_edu", user.getUserEdu());
        }
        IPage<User> result = super.page(userPage, queryWrapper);
        List<User> records = result.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            for (User record : records) {
                List<Role> roles = roleService.findAllRoleByUserId(record.getId());
                record.setRoles(roles);
            }
        }

        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<User> saveUser(User user) {

        /* 初始化密码 */
        String password = new BCryptPasswordEncoder().encode(user.getUserName());
        user.setPassword(password);

        LocalDateTime now = LocalDateTime.now();
        user.setAge(calcAge(now, user.getBirth()));
        user.setCreateTime(now);
        user.setUpdateTime(now);
        /* 1. 根据部门编码查询部门名称 */
        Dept dept = deptService.getById(user.getDeptId());
        /* 2. 保存用户信息 */
        user.setDeptName(dept.getDeptName());
        super.save(user);
        /* 3. 保存用户角色关联信息*/
        this.saveUserRole(user);

        return new Result<>(StatusCode.OK, "保存成功", user);
    }

    /**
     * 计算年龄
     * @param now
     * @param birth
     * @return
     */
    private int calcAge(LocalDateTime now, String birth) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate birthDate = LocalDate.parse(birth, formatter);
        int age = now.get(ChronoField.YEAR) - birthDate.get(ChronoField.YEAR);
        return age;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<User> updateUser(User user) {

        LocalDateTime now = LocalDateTime.now();
        user.setUpdateTime(now);
        user.setAge(calcAge(now, user.getBirth()));
        Dept dept = deptService.getById(user.getDeptId());
        user.setDeptName(dept.getDeptName());
        super.updateById(user);

        /* 重建用户角色关联*/
        this.deleteUserRole(user.getId());
        this.saveUserRole(user);
        return new Result<>(StatusCode.OK, "更新成功", user);
    }

    @Override
    public Result deleteUser(Integer userId) {

        super.removeById(userId);
        this.deleteUserRole(userId);
        return new Result(StatusCode.OK, "删除成功");
    }

    /**
     * 保存用户角色关联信息
     *
     * @param user
     */
    private void saveUserRole(User user) {
        List<Integer> roleIds = user.getRoleIds();
        if (CollectionUtils.isNotEmpty(roleIds)) {
            List<UserRole> userRoles = new ArrayList<>();
            for (Integer roleId : roleIds) {
                UserRole userRole = new UserRole();
                userRole.setRoleId(roleId);
                userRole.setUserId(user.getId());
                userRoles.add(userRole);
            }
            userRoleService.saveBatch(userRoles);
        }
    }

    /**
     * 删除用户角色关联信息
     *
     * @param userId
     */
    private void deleteUserRole(Integer userId) {
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRole::getUserId, userId);
        userRoleService.remove(queryWrapper);
    }
}
